package com.smartcampusbackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.smartcampusbackend.mapper.CourseMapper;
import com.smartcampusbackend.mapper.StudentCourseMapper;
import com.smartcampusbackend.model.Course;
import com.smartcampusbackend.model.StudentCourse;
import com.smartcampusbackend.service.CourseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Map;
import java.util.HashMap;
import com.smartcampusbackend.model.User;
import com.smartcampusbackend.mapper.UserMapper;
import com.smartcampusbackend.model.OperationLog;
import com.smartcampusbackend.service.OperationLogService;
import com.smartcampusbackend.mapper.GradeMapper;
import com.smartcampusbackend.model.Grade;

@Service
public class CourseServiceImpl implements CourseService {
    
    private static final Logger logger = LoggerFactory.getLogger(CourseServiceImpl.class);
    
    @Autowired
    private CourseMapper courseMapper;
    
    @Autowired
    private StudentCourseMapper studentCourseMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OperationLogService operationLogService;

    @Autowired
    private GradeMapper gradeMapper;

    @Override
    public List<Course> listAllCourses() {
        logger.info("获取所有课程");
        try {
            List<Course> courses = courseMapper.selectList(null);
            logger.info("获取到{}门课程", courses.size());
            return courses;
        } catch (Exception e) {
            logger.error("获取所有课程失败", e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<Course> listSelectedCourses(String studentId) {
        logger.info("获取学生已选课程 - studentId: {}", studentId);
        try {
            // 获取学生选课记录
            QueryWrapper<StudentCourse> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_id", studentId);
            List<StudentCourse> selectedCourses = studentCourseMapper.selectList(queryWrapper);
            logger.info("查询到的选课记录数量: {}", selectedCourses.size());
            
            if (selectedCourses.isEmpty()) {
                logger.info("学生{}没有选课记录", studentId);
                return new ArrayList<>();
            }
            
            // 获取已选课程ID列表
            List<String> selectedCourseIds = selectedCourses.stream()
                    .map(StudentCourse::getCourseId)
                    .collect(Collectors.toList());
            
            logger.info("学生已选课程ID: {}", selectedCourseIds);
            
            // 批量查询课程详情
            List<Course> courses = courseMapper.selectBatchIds(selectedCourseIds);
            logger.info("成功获取到{}门已选课程", courses.size());
            
            return courses;
        } catch (Exception e) {
            logger.error("获取已选课程失败", e);
            return new ArrayList<>();
        }
    }

    @Override
    @Transactional
    public boolean selectCourse(String studentId, String courseId) {
        logger.info("学生选课 - studentId: {}, courseId: {}", studentId, courseId);
        try {
            // 查询课程是否存在且未满
            Course course = courseMapper.selectById(courseId);
            
            if (course == null) {
                logger.warn("课程不存在，courseId: {}", courseId);
                return false;
            }
            
            logger.info("查询到的课程: {}", course.getName());
            
            if (course.getCurrentStudents() >= course.getCapacity()) {
                logger.warn("课程已满，当前人数: {}, 容量: {}", course.getCurrentStudents(), course.getCapacity());
                return false;
            }
            
            // 检查是否已经选过这门课
            QueryWrapper<StudentCourse> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_id", studentId).eq("course_id", courseId);
            StudentCourse existingSelection = studentCourseMapper.selectOne(queryWrapper);
            
            if (existingSelection != null) {
                logger.warn("学生已经选过这门课，studentId: {}, courseId: {}", studentId, courseId);
                return false;
            }
            
            // 创建选课记录
            StudentCourse studentCourse = new StudentCourse();
            studentCourse.setStudentId(studentId);
            studentCourse.setCourseId(courseId);
            studentCourse.setSelectionDate(new Date());
            
            // 更新课程已选人数
            course.setCurrentStudents(course.getCurrentStudents() + 1);
            int updateResult = courseMapper.updateById(course);
            logger.info("更新课程人数结果: {}", updateResult > 0 ? "成功" : "失败");
            
            // 插入选课记录
            int insertResult = studentCourseMapper.insert(studentCourse);
            logger.info("插入选课记录结果: {}", insertResult > 0 ? "成功" : "失败");
            
            return insertResult > 0;
        } catch (Exception e) {
            logger.error("选课失败", e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean withdrawCourse(String studentId, String courseId) {
        logger.info("学生退课 - studentId: {}, courseId: {}", studentId, courseId);
        try {
            // 查询课程是否存在
            Course course = courseMapper.selectById(courseId);
            if (course == null) {
                logger.warn("课程不存在，courseId: {}", courseId);
                return false;
            }
            logger.info("查询到的课程: {}", course.getName());
            
            // 检查是否已经选过这门课
            QueryWrapper<StudentCourse> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_id", studentId).eq("course_id", courseId);
            StudentCourse existingSelection = studentCourseMapper.selectOne(queryWrapper);
            if (existingSelection == null) {
                logger.warn("未选过这门课，studentId: {}, courseId: {}", studentId, courseId);
                return false;
            }

            // 检查是否已录入成绩，不可退课
            QueryWrapper<Grade> gradeQuery = new QueryWrapper<>();
            gradeQuery.eq("student_id", studentId).eq("course_id", courseId);
            Grade grade = gradeMapper.selectOne(gradeQuery);
            if (grade != null && (grade.getRegularGrade() != null || grade.getExamGrade() != null || grade.getFinalGrade() != null)) {
                logger.warn("已录入成绩，不可退课，studentId: {}, courseId: {}", studentId, courseId);
                return false;
            }
            
            // 更新课程已选人数
            if (course.getCurrentStudents() > 0) {
                course.setCurrentStudents(course.getCurrentStudents() - 1);
                int updateResult = courseMapper.updateById(course);
                logger.info("更新课程人数结果: {}", updateResult > 0 ? "成功" : "失败");
            }
            
            // 删除选课记录
            int deleteResult = studentCourseMapper.delete(queryWrapper);
            logger.info("删除选课记录结果: {}", deleteResult > 0 ? "成功" : "失败");
            
            return deleteResult > 0;
        } catch (Exception e) {
            logger.error("退课失败", e);
            return false;
        }
    }

    @Override
    public List<Course> listTeacherCourses(String teacherId) {
        logger.info("获取教师课程 - teacherId: {}", teacherId);
        try {
            QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("teacher_id", teacherId);
            List<Course> courses = courseMapper.selectList(queryWrapper);
            logger.info("教师{}有{}门课程", teacherId, courses.size());
            return courses;
        } catch (Exception e) {
            logger.error("获取教师课程失败", e);
            return new ArrayList<>();
        }
    }

    @Override
    public boolean createCourse(Course course) {
        logger.info("创建新课程: {}", course.getName());
        try {
            // 1. 时间冲突校验（同一教师、同一学期、同一天同一时间段不能重复）
            QueryWrapper<Course> conflictWrapper = new QueryWrapper<>();
            conflictWrapper.eq("teacher_id", course.getTeacherId())
                .eq("semester", course.getSemester())
                .eq("schedule", course.getSchedule());
            long conflictCount = courseMapper.selectCount(conflictWrapper);
            if (conflictCount > 0) {
                logger.warn("课程时间冲突: 教师{} {} {} {}", course.getTeacherId(), course.getSemester(), course.getSchedule(), course.getName());
                return false;
            }
            // 2. 必修课自动同步当前选课人数，不覆盖容量
            if ("必修课程".equals(course.getType())) {
                List<User> students = userMapper.selectStudentsByDepartmentAndMajor(course.getDepartmentId(), course.getMajorId());
                int studentCount = (students != null) ? students.size() : 0;
                course.setCurrentStudents(studentCount);
                // 不自动 setCapacity，capacity 由教师设置
            } else {
            course.setCurrentStudents(0);
            }
            int result = courseMapper.insert(course);
            logger.info("创建课程结果: {}, 课程ID: {}", result > 0 ? "成功" : "失败", course.getId());
            return result > 0;
        } catch (Exception e) {
            logger.error("创建课程失败", e);
            return false;
        }
    }

    @Override
    public boolean updateCourse(Course course) {
        logger.info("更新课程 - courseId: {}, name: {}", course.getId(), course.getName());
        try {
            // 获取原课程信息
            Course existingCourse = courseMapper.selectById(course.getId());
            if (existingCourse == null) {
                logger.warn("课程不存在，courseId: {}", course.getId());
                return false;
            }
            // 1. 时间冲突校验（排除自己）
            QueryWrapper<Course> conflictWrapper = new QueryWrapper<>();
            conflictWrapper.eq("teacher_id", course.getTeacherId())
                .eq("semester", course.getSemester())
                .eq("schedule", course.getSchedule())
                .ne("id", course.getId());
            long conflictCount = courseMapper.selectCount(conflictWrapper);
            if (conflictCount > 0) {
                logger.warn("课程时间冲突: 教师{} {} {} {}", course.getTeacherId(), course.getSemester(), course.getSchedule(), course.getName());
                return false;
            }
            // 2. 必修课自动同步当前选课人数，不覆盖容量
            if ("必修课程".equals(course.getType())) {
                List<User> students = userMapper.selectStudentsByDepartmentAndMajor(course.getDepartmentId(), course.getMajorId());
                int studentCount = (students != null) ? students.size() : 0;
                course.setCurrentStudents(studentCount);
                // 不自动 setCapacity，capacity 由教师设置
            } else {
            // 保留当前选课人数
            course.setCurrentStudents(existingCourse.getCurrentStudents());
            }
            int result = courseMapper.updateById(course);
            logger.info("更新课程结果: {}", result > 0 ? "成功" : "失败");
            return result > 0;
        } catch (Exception e) {
            logger.error("更新课程失败", e);
            return false;
        }
    }

    @Override
    public boolean deleteCourse(String courseId, String teacherId) {
        logger.info("教师删除课程 - courseId: {}, teacherId: {}", courseId, teacherId);
        try {
            // 检查是否是该教师的课程
            QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("id", courseId).eq("teacher_id", teacherId);
            Course course = courseMapper.selectOne(queryWrapper);
            
            if (course == null) {
                logger.warn("课程不存在或不属于该教师");
                return false;
            }
            
            // 删除选课记录
            QueryWrapper<StudentCourse> scQueryWrapper = new QueryWrapper<>();
            scQueryWrapper.eq("course_id", courseId);
            int deleteScResult = studentCourseMapper.delete(scQueryWrapper);
            logger.info("删除选课记录结果: {}, 删除记录数: {}", deleteScResult >= 0 ? "成功" : "失败", deleteScResult);
            
            // 删除课程
            int deleteCourseResult = courseMapper.deleteById(courseId);
            logger.info("删除课程结果: {}", deleteCourseResult > 0 ? "成功" : "失败");
            
            return deleteCourseResult > 0;
        } catch (Exception e) {
            logger.error("删除课程失败", e);
            return false;
        }
    }

    @Override
    public boolean deleteCourseByAdmin(String courseId) {
        logger.info("管理员删除课程 - courseId: {}", courseId);
        try {
            // 删除选课记录
            QueryWrapper<StudentCourse> scQueryWrapper = new QueryWrapper<>();
            scQueryWrapper.eq("course_id", courseId);
            int deleteScResult = studentCourseMapper.delete(scQueryWrapper);
            logger.info("删除选课记录结果: {}, 删除记录数: {}", deleteScResult >= 0 ? "成功" : "失败", deleteScResult);
            
            // 删除课程
            int deleteCourseResult = courseMapper.deleteById(courseId);
            logger.info("删除课程结果: {}", deleteCourseResult > 0 ? "成功" : "失败");
            
            return deleteCourseResult > 0;
        } catch (Exception e) {
            logger.error("管理员删除课程失败", e);
            return false;
        }
    }

    @Override
    public List<Course> listCoursesByDepartmentAndMajor(Long departmentId, Long majorId) {
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        if (departmentId != null) {
            queryWrapper.eq("department_id", departmentId);
        }
        if (majorId != null) {
            queryWrapper.eq("major_id", majorId);
        }
        return courseMapper.selectList(queryWrapper);
    }

    @Override
    public boolean selectRequiredCourses(String studentId, Long departmentId, Long majorId) {
        // 获取指定院系专业的所有必修课
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("department_id", departmentId)
                    .eq("major_id", majorId)
                    .eq("type", "必修课程");
        List<Course> requiredCourses = courseMapper.selectList(queryWrapper);
        
        // 获取该院系专业所有学生
        List<User> students = userMapper.selectStudentsByDepartmentAndMajor(departmentId, majorId);
        boolean allSuccess = true;
        for (Course course : requiredCourses) {
            for (User student : students) {
                boolean success = selectCourse(student.getId().toString(), course.getId());
                if (success) {
                    // 写入日志
                    OperationLog log = new OperationLog();
                    log.setBusinessType("选课");
                    log.setBusinessId(course.getId());
                    log.setOperationType("自动选必修课");
                    log.setOperatorId(student.getId().toString());
                    log.setOperatorName(student.getRealName() != null ? student.getRealName() : student.getUsername());
                    log.setOperatorRole("学生");
                    log.setContent("系统为学生 " + log.getOperatorName() + " 自动选中必修课程：" + course.getName());
                    log.setStatus("完成");
                    log.setIsSignature(false);
                    log.setCreateTime(new java.util.Date());
                    operationLogService.addLog(log);
                } else {
                allSuccess = false;
                }
            }
            // 更新课程容量为当前学生数（只同步 currentStudents，不覆盖 capacity）
            int studentCount = (students != null) ? students.size() : 0;
            course.setCurrentStudents(studentCount);
            // 不自动 setCapacity，capacity 由教师设置
            courseMapper.updateById(course);
        }
        return allSuccess;
    }

    @Override
    public List<Map<String, Object>> generateCourseSchedule(String studentId) {
        List<Course> selectedCourses = listSelectedCourses(studentId);
        List<Map<String, Object>> scheduleData = new ArrayList<>();
        
        // 将课程按时间段整理成课程表格式
        for (Course course : selectedCourses) {
            if (course.getSchedule() == null || course.getSchedule().isEmpty()) {
                continue;
            }
            
            String[] timeSlots = course.getSchedule().split("星期");
            for (int i = 1; i < timeSlots.length; i++) {
                String timeSlot = "星期" + timeSlots[i].trim();
                Map<String, Object> scheduleItem = new HashMap<>();
                scheduleItem.put("courseName", course.getName());
                scheduleItem.put("timeSlot", timeSlot);
                scheduleItem.put("location", course.getLocation());
                scheduleData.add(scheduleItem);
            }
        }
        
        return scheduleData;
    }

    // 新增：支持按学生专业筛选课程
    public List<Course> listAllCourses(String studentId) {
        if (studentId == null || studentId.isEmpty()) {
            return listAllCourses();
        }
        User student = userMapper.selectById(studentId);
        if (student == null) {
            return new ArrayList<>();
        }
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("department_id", student.getDepartmentId())
                    .eq("major_id", student.getMajorId());
        List<Course> courses = courseMapper.selectList(queryWrapper);
        logger.info("按专业筛选课程，studentId={}, 院系={}, 专业={}, 课程数={}", studentId, student.getDepartmentId(), student.getMajorId(), courses.size());
        return courses;
    }
} 